

#include <sqlite3.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include<stdlib.h>

int custom_sstrptime(const char *str, const char *format, struct tm *tm) {
    const char *s = str;
    const char *f = format;

    while (*f) {
        if (*f == '%') {
            f++;
            switch (*f) {
                case 'Y': // Year
                    if (sscanf(s, "%4d", &tm->tm_year) != 1) return 0;
                    tm->tm_year -= 1900; // tm_year is years since 1900
                    s += 4;
                    break;
                case 'm': // Month
                    if (sscanf(s, "%2d", &tm->tm_mon) != 1) return 0;
                    tm->tm_mon -= 1; // tm_mon is 0-based
                    s += 2;
                    break;
                case 'd': // Day
                    if (sscanf(s, "%2d", &tm->tm_mday) != 1) return 0;
                    s += 2;
                    break;
                case 'H': // Hour
                    if (sscanf(s, "%2d", &tm->tm_hour) != 1) return 0;
                    s += 2;
                    break;
                case 'M': // Minute
                    if (sscanf(s, "%2d", &tm->tm_min) != 1) return 0;
                    s += 2;
                    break;
                case 'S': // Second
                    if (sscanf(s, "%2d", &tm->tm_sec) != 1) return 0;
                    s += 2;
                    break;
                default:
                    return 0; // Unsupported format
            }
        } else {
            if (*s != *f) return 0;
            s++;
        }
        f++;
    }

    return 1; // Success
}


// 逾期处理核心函数
void handle_overdue_penalty(sqlite3 *db, int user_id, int book_id) {
    char *err_msg = NULL;
    time_t now = time(NULL);
    
    // 1. 获取借阅记录信息
    char sql[512];
    snprintf(sql, sizeof(sql),
             "SELECT borrow_date, due_date, return_date "
             "FROM borrow_records "
             "WHERE user_id=%d AND book_id=%d;",
             user_id, book_id);
    
    sqlite3_stmt *stmt;
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    
    if (rc != SQLITE_OK || sqlite3_step(stmt) != SQLITE_ROW) {
        fprintf(stderr, "无法获取借阅记录: %s\n", sqlite3_errmsg(db));
        return;
    }
    
    // 解析日期
    const char *borrow_date_str = (const char *)sqlite3_column_text(stmt, 0);
    const char *return_date_str = (const char *)sqlite3_column_text(stmt, 1);
    
    // 获取当前日期（不含时间部分)
    struct tm *now_tm = localtime(&now);
    now_tm->tm_hour = 0;
    now_tm->tm_min = 0;
    now_tm->tm_sec = 0;
    time_t today = mktime(now_tm);
    
    // 解析借书日期
    struct tm borrow_tm = {0};
    custom_sstrptime(borrow_date_str, "%Y-%m-%d", &borrow_tm);
    time_t borrow_time = mktime(&borrow_tm);
    
    // 2. 计算借书后天数（从借书当天开始计算）
    int days_since_borrow = (int)(difftime(today, borrow_time) / (24 * 60 * 60));
    
    // 3. 分级警告系统（基于借书后的天数）
    if (days_since_borrow >= 7 && return_date_str == NULL) {
        if (days_since_borrow == 7) {
            printf("发送第一次警告邮件给用户 %d...\n", user_id);
            // 实际应用中这里会发送邮件 
        }
        else if (days_since_borrow >= 10) {
            printf("发送信誉警告通知给用户 %d...\n", user_id);
            //实际应用也会发送邮件 
            printf("账户冻结！不能借阅新书\n");
            
            // 冻结账户（直到还书）
            snprintf(sql, sizeof(sql),
                     "UPDATE users SET penalty_end='9999-12-31' WHERE id=%d;",
                     user_id);
            sqlite3_exec(db, sql, 0, 0, &err_msg);
        }
    }
    
    // 4. 还书后的惩罚（保持不变）
  if (return_date_str != NULL) {
        // 解析还书日期
        struct tm return_tm = {0};
        custom_sstrptime(return_date_str, "%Y-%m-%d", &return_tm);
        time_t return_time = mktime(&return_tm);
        
        // 计算借书到还书的总天数
        int total_borrow_days = (int)(difftime(return_time, borrow_time) / (24 * 60 * 60));
        
        // 如果总借书天数超过10天，则进行惩罚
        if (total_borrow_days > 10) {
            // 惩罚天数 = 超过10天的天数
            int penalty_days = total_borrow_days - 10;
            time_t penalty_end = return_time + penalty_days * 24 * 60 * 60;
            
            struct tm *penalty_tm = localtime(&penalty_end);
            char penalty_end_str[20];
            strftime(penalty_end_str, sizeof(penalty_end_str), "%Y-%m-%d", penalty_tm);
            
            // 应用惩罚
            snprintf(sql, sizeof(sql),
                     "UPDATE users SET penalty_end='%s' WHERE id=%d;",
                     penalty_end_str, user_id);
            sqlite3_exec(db, sql, 0, 0, &err_msg);
            
            printf("用户 %d 受到惩罚：%d 天内不能借书（直到 %s）\n", 
                   user_id, penalty_days, penalty_end_str);
        }
    }
    
    sqlite3_finalize(stmt);

}

// 借阅图书时调用
int borrow_book(sqlite3 *db, int user_id, int book_id) {
    // ... 其他借书逻辑 ...
    
    // 设置7天后到期
    time_t now = time(NULL);
    time_t due_time = now + 7 * 24 * 60 * 60;
    struct tm *due_tm = localtime(&due_time);
    char due_str[20];
    strftime(due_str, sizeof(due_str), "%Y-%m-%d", due_tm);
    
    // ... 保存借阅记录 ...
    
    // 设置定时器检查（实际应用中会使用cron或定时任务）
    printf("将在7天后（%s）检查是否归还\n", due_str);
    
    return 1;
}

// 归还图书时调用
int return_book(sqlite3 *db, int user_id, int book_id) {
    // ... 其他还书逻辑 ...
    
    // 处理逾期惩罚
    handle_overdue_penalty(db, user_id, book_id);
    
    return 1;
}



// 创建数据库和表
void initialize_database(sqlite3 **db) {
    int rc = sqlite3_open(":memory:", db); // 使用内存数据库
    if (rc != SQLITE_OK) {
        fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(*db));
        exit(1);
    }

    // 创建用户表
    const char *create_users = "CREATE TABLE users ("
                               "id INTEGER PRIMARY KEY, "
                               "name TEXT, "
                               "penalty_end DATE);";
    
    // 创建借阅记录表
    const char *create_borrows = "CREATE TABLE borrow_records ("
                                 "user_id INTEGER, "
                                 "book_id INTEGER, "
                                 "borrow_date DATE NOT NULL, "
                                 "due_date DATE, "
                                 "return_date DATE);";
    
    char *err_msg = NULL;
    sqlite3_exec(*db, create_users, 0, 0, &err_msg);
    sqlite3_exec(*db, create_borrows, 0, 0, &err_msg);
    
    // 插入测试用户
    sqlite3_exec(*db, "INSERT INTO users (id, name) VALUES (1, '张三');", 0, 0, 0);
    sqlite3_exec(*db, "INSERT INTO users (id, name) VALUES (2, '李四');", 0, 0, 0);
    sqlite3_exec(*db, "INSERT INTO users (id, name) VALUES (3, '王五');", 0, 0, 0);
    
    printf("数据库初始化完成\n");
}

// 模拟借书操作
void simulate_borrow(sqlite3 *db, int user_id, int book_id, const char *borrow_date) {
    char sql[256];
    snprintf(sql, sizeof(sql),
             "INSERT INTO borrow_records (user_id, book_id, borrow_date) "
             "VALUES (%d, %d, '%s');",
             user_id, book_id, borrow_date);
    
    char *err_msg = NULL;
    sqlite3_exec(db, sql, 0, 0, &err_msg);
    
    printf("用户 %d 在 %s 借阅了书籍 %d\n", user_id, borrow_date, book_id);
}

// 模拟还书操作
void simulate_return(sqlite3 *db, int user_id, int book_id, const char *return_date) {
    char sql[256];
    snprintf(sql, sizeof(sql),
             "UPDATE borrow_records SET return_date = '%s' "
             "WHERE user_id = %d AND book_id = %d;",
             return_date, user_id, book_id);
    
    char *err_msg = NULL;
    sqlite3_exec(db, sql, 0, 0, &err_msg);
    
    printf("用户 %d 在 %s 归还了书籍 %d\n", user_id, return_date, book_id);
    return_book(db, user_id, book_id);
}

// 打印用户状态的回调函数
int print_user_status(void *data, int argc, char **argv, char **colName) {
    printf("用户ID: %s, 姓名: %s, 惩罚截止日: %s\n", 
           argv[0], 
           argv[1], 
           argv[2] ? argv[2] : "无");
    return 0;
}

// 打印借阅记录的回调函数
int print_borrow_status(void *data, int argc, char **argv, char **colName) {
    printf("用户ID: %s, 书籍ID: %s\n", argv[0], argv[1]);
    printf("借阅日期: %s, 到期日: %s, 归还日: %s\n\n", 
           argv[2], 
           argv[3] ? argv[3] : "N/A", 
           argv[4] ? argv[4] : "未归还");
    return 0;
}

void daily_check(sqlite3 *db) {
    printf("\n=== 每日逾期检查 ===\n");
    
    char *err_msg = NULL;
    const char *sql = "SELECT user_id, book_id, borrow_date "
                     "FROM borrow_records WHERE return_date IS NULL;";
    
    sqlite3_stmt *stmt;
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    
    if (rc != SQLITE_OK) {
        fprintf(stderr, "查询失败: %s\n", sqlite3_errmsg(db));
        return;
    }
    
    // 获取当前日期（不含时间部分）
    time_t now = time(NULL);
    struct tm *now_tm = localtime(&now);
    now_tm->tm_hour = 0;
    now_tm->tm_min = 0;
    now_tm->tm_sec = 0;
    time_t today = mktime(now_tm);
    
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int user_id = sqlite3_column_int(stmt, 0); // 第0列: user_id
        int book_id = sqlite3_column_int(stmt, 1); // 第1列: book_id (修复这里)
        const char *borrow_date_str = (const char *)sqlite3_column_text(stmt, 2); // 第2列: borrow_date
        
        printf("检查用户 %d 的书籍 %d (借阅日期: %s)\n", user_id, book_id, borrow_date_str);
        
        // 解析借书日期
        struct tm borrow_tm = {0};
        custom_sstrptime(borrow_date_str, "%Y-%m-%d", &borrow_tm);
        time_t borrow_time = mktime(&borrow_tm);
        
        // 计算借书后天数
        int days_since_borrow = (int)(difftime(today, borrow_time) / (24 * 60 * 60));
        printf("已借阅 %d 天\n", days_since_borrow);
        
        // 只处理借书7天后的记录
        if (days_since_borrow >= 7) {
            handle_overdue_penalty(db, user_id, book_id);
        }
    }
    
    sqlite3_finalize(stmt);
}

// 在 main 函数中添加错误检查和调试输出
int main() {
    sqlite3 *db;
    char *err_msg = NULL;
    
    printf("当前时间: %s\n", __DATE__ " " __TIME__);
    
    // 初始化内存数据库
    if (sqlite3_open(":memory:", &db) != SQLITE_OK) {
        fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
        return 1;
    }
    
    initialize_database(&db);
    printf("===== 数据库初始化完成 =====\n\n");
    
    // 测试场景1: 按时归还（无惩罚）
    printf("===== 场景1: 按时归还 =====\n");
    simulate_borrow(db, 1, 1001, "2025-01-01");
    simulate_return(db, 1, 1001, "2025-01-05");
    printf("\n");
    
    // 测试场景2: 轻微逾期（警告）
    printf("===== 场景2: 轻微逾期 =====\n");
    simulate_borrow(db, 2, 2001, "2025-01-01");
    printf("\n[模拟第7天检查]\n");
    daily_check(db);
    printf("\n");
    
    // 测试场景3: 严重逾期（账户冻结）
    printf("===== 场景3: 严重逾期 =====\n");
    simulate_borrow(db, 3, 3001, "2025-01-01");
    printf("\n[模拟第10天检查]\n");
    daily_check(db);
    printf("\n[用户3尝试借新书]\n");
    simulate_borrow(db, 3, 3002, "2025-01-10");
    printf("\n");
    
    // 测试场景4: 逾期后归还（惩罚计算）
    printf("===== 场景4: 逾期后归还 =====\n");
    simulate_borrow(db, 2, 2002, "2025-01-05");
    simulate_return(db, 2, 2002, "2025-01-20");
    printf("\n");
    
    // 测试场景5: 冻结后归还（解除冻结）
    printf("===== 场景5: 冻结后归还 =====\n");
    simulate_return(db, 3, 3001, "2025-01-15");
    printf("\n[用户3再次尝试借书]\n");
    simulate_borrow(db, 3, 3003, "2025-01-16");
    printf("\n");
    
    // 最终状态检查
    printf("===== 最终用户状态 =====\n");
    const char *user_status_sql = "SELECT id, name, penalty_end FROM users;";
    if (sqlite3_exec(db, user_status_sql, print_user_status, 0, &err_msg) != SQLITE_OK) {
        fprintf(stderr, "查询失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }
    
    printf("\n===== 最终借阅记录 =====\n");
    const char *borrow_status_sql = "SELECT * FROM borrow_records;";
    if (sqlite3_exec(db, borrow_status_sql, print_borrow_status, 0, &err_msg) != SQLITE_OK) {
        fprintf(stderr, "查询失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }
    
    // 清理
    sqlite3_close(db);
    return 0;
}